/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bizentity.util.changeset;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.inspur.edp.bef.bizentity.GspBizEntityElement;
import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.operation.BizMgrAction;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ActionChangeDetail;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ActionChangeSet;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ChangeType;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ElementChangeDetail;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ElementChangeSet;
import com.inspur.edp.bef.bizentity.pushchangesetargs.MetadataInfo;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ObjectChangeDetail;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ObjectChangeSet;
import com.inspur.edp.bef.bizentity.pushchangesetargs.PushChangeSet;
import com.inspur.edp.bef.bizentity.pushchangesetargs.RelatedMetadata;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class ChangeSetInfoUtil {

  public static PushChangeSet getChangeSetInfo(JsonNode info) {
    if (StringUtil.checkNull(info)) {
      return null;
    }
    PushChangeSet changeSet = new PushChangeSet();
    try {
      if (!StringUtil.checkNull(info.get(ChangeSetConst.metadataInfo))) {
        changeSet.setMetadataInfo(new ObjectMapper()
            .treeToValue(info.get(ChangeSetConst.metadataInfo), MetadataInfo.class));
      }
      changeSet.setRelatedMetadatas(getRelateMetadatas(info));
      changeSet.setActionChangeSets(getActionChangeSet(info));
      changeSet.setObjectChangeSets(getObjectChangeSets(info));
      changeSet.setElementChangeSets(getElementChangeSets(info));
    } catch (JsonProcessingException e) {
      e.printStackTrace();
    }
    return changeSet;
  }


  static List<RelatedMetadata> getRelateMetadatas(JsonNode info) throws JsonProcessingException {
    if (StringUtil.checkNull(info.get(ChangeSetConst.relatedMetadatas))) {
      return null;
    }
    List<RelatedMetadata> metadataList = new ArrayList<>();
    if (StringUtil.checkNull(info.get(ChangeSetConst.relatedMetadatas))) {
      return metadataList;
    }
    ;
    Iterator iter = info.get(ChangeSetConst.relatedMetadatas).iterator();
    while (iter.hasNext()) {
      metadataList
          .add(new ObjectMapper().treeToValue((ObjectNode) iter.next(), RelatedMetadata.class));
    }
    return metadataList;
  }

  static List<ActionChangeSet> getActionChangeSet(JsonNode info) throws JsonProcessingException {
    if (StringUtil.checkNull(info.get(ChangeSetConst.actionChangeSet))) {
      return null;
    }
    List<ActionChangeSet> changeSetList = new ArrayList<>();
    Iterator iter = info.get(ChangeSetConst.actionChangeSet).iterator();
    while (iter.hasNext()) {
      ObjectNode node = (ObjectNode) iter.next();

      ObjectNode detailNode = (ObjectNode) node.get(ChangeSetConst.changeDetail);
      String type = node.get(ChangeSetConst.changeType).textValue();

      if (StringUtil.checkNull(detailNode) | StringUtil.checkNull(type)) {
        continue;
      }
      ActionChangeDetail detail = new ActionChangeDetail();
      detail.setActionId(detailNode.get(ChangeSetConst.actionId).textValue());
      detail.setActionCode(detailNode.get(ChangeSetConst.actionCode).textValue());
      if (!StringUtil.checkNull(detailNode.get(ChangeSetConst.parameterId))) {
        detail.setParameterId(detailNode.get(ChangeSetConst.parameterId).textValue());
      }
      if (!StringUtil.checkNull(detailNode.get(ChangeSetConst.parameterCode))) {
        detail.setParameterCode(detailNode.get(ChangeSetConst.parameterCode).textValue());
      }
      detail.setNecessary(detailNode.get(ChangeSetConst.isNecessary).asBoolean());
//            if (!StringUtil.checkNull(detailNode.get(ChangeSetConst.changeDetail))) {
      detail.setChangeInfo(
          new ObjectMapper().treeToValue(detailNode.get(ChangeSetConst.changeInfo), Map.class));
//            }
      if (!StringUtil.checkNull(detailNode.get(ChangeSetConst.mgrAction))) {
        detail.setMgrAction(new ObjectMapper()
            .treeToValue(detailNode.get(ChangeSetConst.mgrAction), BizMgrAction.class));
      }
      changeSetList.add(new ActionChangeSet(detail, ChangeType.valueOf(type)));
    }
    return changeSetList;
  }

  public static List<ObjectChangeSet> getObjectChangeSets(JsonNode info)
      throws JsonProcessingException {
    if (StringUtil.checkNull(info.get(ChangeSetConst.objectChangeSets))) {
      return null;
    }
    List<ObjectChangeSet> changeSetList = new ArrayList<>();
    Iterator iter = info.get(ChangeSetConst.objectChangeSets).iterator();
    while (iter.hasNext()) {
      ObjectNode node = (ObjectNode) iter.next();
      ObjectNode detailNode = (ObjectNode) node.get(ChangeSetConst.changeDetail);
      String type = node.get(ChangeSetConst.changeType).textValue();

      if (StringUtil.checkNull(detailNode) | StringUtil.checkNull(type)) {
        continue;
      }
      ObjectChangeDetail detail = new ObjectChangeDetail();
      detail.setBizObjectId(detailNode.get(ChangeSetConst.bizObjectId).textValue());
      detail.setBizObjectCode(detailNode.get(ChangeSetConst.bizObjectCode).textValue());
      detail.setNecessary(detailNode.get(ChangeSetConst.isNecessary).asBoolean());
      if (!StringUtil.checkNull(detailNode.get(ChangeSetConst.parentObjIDElementId))) {
        detail.setParentObjIDElementId(
            detailNode.get(ChangeSetConst.parentObjIDElementId).textValue());
      }
//            if (StringUtil.checkNull(detailNode.get(ChangeSetConst.changeDetail))) {
      detail.setChangeInfo(
          new ObjectMapper().treeToValue(detailNode.get(ChangeSetConst.changeInfo), Map.class));
//            }
      if (detailNode.get(ChangeSetConst.bizObject) != null) {
        detail.setBizObject(new ObjectMapper()
            .treeToValue(detailNode.get(ChangeSetConst.bizObject), GspBizEntityObject.class));
      }
      changeSetList.add(new ObjectChangeSet(detail, ChangeType.valueOf(type)));
    }
    return changeSetList;
  }

  public static List<ElementChangeSet> getElementChangeSets(JsonNode info)
      throws JsonProcessingException {
    if (StringUtil.checkNull(info.get(ChangeSetConst.elementChangeSets))) {
      return null;
    }
    List<ElementChangeSet> changeSetList = new ArrayList<>();
    Iterator iter = info.get(ChangeSetConst.elementChangeSets).iterator();
    while (iter.hasNext()) {
      ObjectNode node = (ObjectNode) iter.next();
      ObjectNode detailNode = (ObjectNode) node.get(ChangeSetConst.changeDetail);
      String type = node.get(ChangeSetConst.changeType).textValue();

      if (StringUtil.checkNull(detailNode) | StringUtil.checkNull(type)) {
        continue;
      }
      ElementChangeDetail detail = new ElementChangeDetail();
      detail.setBizObjectId(detailNode.get(ChangeSetConst.bizObjectId).textValue());
      detail.setBizObjectCode(detailNode.get(ChangeSetConst.bizObjectCode).textValue());
      detail.setBizElementId(detailNode.get(ChangeSetConst.bizElementId).textValue());
      //TODO: 前端偶发性没有elementCode, 项目演示临时兼容
      JsonNode elementCodeJson = detailNode.get(ChangeSetConst.bizElementCode);
      if (elementCodeJson != null) {
        detail.setBizElementCode(elementCodeJson.textValue());
      }
//            if (StringUtil.checkNull(detailNode.get(ChangeSetConst.changeDetail))) {
      detail.setChangeInfo(
          new ObjectMapper().treeToValue(detailNode.get(ChangeSetConst.changeInfo), Map.class));
//            }
      if (!StringUtil.checkNull(detailNode.get(ChangeSetConst.bizElement))) {
        detail.setBizElement(new ObjectMapper()
            .treeToValue(detailNode.get(ChangeSetConst.bizElement), GspBizEntityElement.class));
      }
      changeSetList.add(new ElementChangeSet(detail, ChangeType.valueOf(type)));
    }
    return changeSetList;
  }

}
